{
    class Role extends ui.Room.Com.RoleStatusBarUI {
        constructor() {
            super();

            this.pivotX = 40;
            this.pivotY = 150;

            this.uid = null;
            this.heroData = null;
            this.hp = 0;
            this.bulletNum = 0;
            this.skillPower = 0;
            this.direct = [0, 0];
            this.speed = 0;
            this.frameNum = 0;
            this.status = [];
            this.speedN = 0;
            this.statusBar = null;

            this.isAttack = false;
            this.isDie = false;
            this._walkStatus = 0;
            this.indicatorActive = false;
            this.invincibleAni = [];
        }

        //创建人物
        //{"cmd":"enter","code":0,"res":{"red":[{"uid":2037586642,"tno":"49047772","ue":"yl*5","mid":2,"um":0,"lr":1,"st":1,"ho":"1","gd":"1","hn":"瑞恩","hl":1,"hm":0,"hp":1000,"w":122,"h":122,"s":500,"m":0,"d":0,"clip":{"max":3,"t":500,"p":{"x":-20,"y":-34,"x1":84,"y1":-56}},"bullet":{"t":1,"s":500,"g":1000,"d":{"h":100,"t":2000,"r":10},"i":{"h":100,"t":2000,"r":10},"b":{"h":100,"t":2000,"r":10}},"averageCup":0,"x":72,"y":792,"mx":1,"my":0}],"roomNo":"b926f57149","blue":[{"uid":2037587422,"tno":"49044510","ue":"balabala","mid":2,"um":0,"lr":1,"st":1,"ho":"1","gd":"1","hn":"沙奎尔","hl":1,"hm":1,"hp":1000,"w":122,"h":122,"s":500,"m":0,"d":0,"clip":{"max":3,"t":500,"p":{"x":-20,"y":-34,"x1":84,"y1":-56}},"bullet":{"t":1,"s":500,"g":1000,"d":{"h":100,"t":2000,"r":10},"i":{"h":100,"t":2000,"r":10},"b":{"h":100,"t":2000,"r":10}},"averageCup":1,"x":4968,"y":792,"mx":-1,"my":0}]}}
        create(data) {
            if (data.ho == '1') {
                this.heroData = { "id": "1", "name": "Ryan", "normal": { "cd": 200, "type": 1, "speed": 500, "asset": "ryan_normal:1", "indicator": { type: 1, range: 300, width: 35 }, "bulletNum": 5 }, "skill": { "cd": 200, "type": 1, "speed": 500, "asset": "ryan_normal:1", "indicator": { type: 1, range: 500, width: 50 }, "bulletNum": 7 }, "speed": 30, "maxHp": 3000, "bulletMaxNum": 3 };
            } else {
                this.heroData = { "id": "2", "name": "Shark", "normal": { "cd": 200, "type": 2, "speed": 500, "asset": "shark_normal:1", "indicator": { type: 2, range: 150, width: 30 }, "bulletNum": 3 }, "skill": { "cd": 200, "type": 2, "speed": 500, "asset": "shark_normal:1", "indicator": { type: 2, range: 300, width: 60 }, "bulletNum": 5 }, "speed": 25, "maxHp": 4000, "bulletMaxNum": 3 };
            }
            this.heroData.maxHp = data.maxhp;
            this.heroData.bulletMaxNum = data.clip.max;
            this.heroData.speed = data.s / 20 ;
            this.heroData.normal.indicator.range = data.bullet.g;
            this.heroData.normal.indicator.speed = data.bullet.s;
            this.uid = data.uid;
            this.camp = data.camp;
            this.hp = this.heroData.maxHp;
            this.bulletNum = this.heroData.bulletMaxNum;
            this.speed = this.heroData.speed;
            //血条，名字颜色
            let res;
            let color;
            if (this.uid == GM.user_id) {
                res = 'hp_self.png';
                color = '#15d615';
            } else if (data.camp == 1) {
                res = 'hp_red.png';
                color = '#ff8373';
            } else {
                res = 'hp_blue.png';
                color = '#3eefff';
            }
            this.hpBar.skin = 'res/game/role/' + res;
            this.lb_name.color = color;
            this.lb_name.text = data.ue;
            this.lb_hp.text = this.hp;
            this.skillPower = 0;

            //渲染弹匣数条
            let space = 1;
            let w = (this.bg.width - space) / this.heroData.bulletMaxNum;
            for (let i = 0; i < this.heroData.bulletMaxNum; i++) {
                let b_bg = new Laya.Image('res/game/role/bulletNum_blank.png');
                b_bg.width = w;
                let tx = i * w + space;
                b_bg.pos(tx, 0);
                this.bg.addChild(b_bg);

                let b = new Laya.Image('res/game/role/bulletNum.png');
                b.pos(tx, 2);
                this['b' + i] = b;
                this.bg.addChild(b);
            }

            //渲染人物骨骼动画
            let className = "Hero." + (this.heroData.name.slice(0, 1).toUpperCase() + this.heroData.name.slice(1));
            this.hero = new (Laya.ClassUtils.getClass(className))();
            this.addChild(this.hero);

            //动作结束后回归原样
            this.hero.on('attack_end', this, () => { this._walkStatus = 0; this.isAttack = false; this.hideIndicator(); });
            this.hero.on('act_end', this, () => { this._walkStatus = 0; });

            //添加阴影
            var shadow = new Laya.Image('res/game/role/role_shadow.png');
            shadow.anchorX = 0.5;
            shadow.anchorY = 0.5;
            shadow.pos(this.pivotX, this.pivotY);
            this.addChildAt(shadow, 0);

            if (this.uid != GM.user_id) {
                return;
            }
            Sail.io.publish('role.move', { x: this.x, y: this.y });

            Sail.io.register({
                "role.change.face": this.showIndicator
            }, this);
        }

        destoryEvent() {
            Sail.io.unregister({
                "role.change.face": this.showIndicator
            }, this);
        }

        roleDie() {
            if(this.uid == GM.user_id){
                Sail.io.publish("role.die");
            }
            this.isDie = true;
            this._walkStatus = -1;
            Laya.timer.clear(this, this.move);
            this.removeSelf();
            let deathAni = Sail.Utils.createSkeleton('res/game/role/death');
            deathAni.zOrder = this.y;
            deathAni.pos(this.x, this.y);
            deathAni.on('stopped', this, () => {
                deathAni.destroy();
                this.event('death');
            });
            Sail.io.publish('map.add', deathAni);
            deathAni.play(0);
            // this.destoryEvent();
            // this.destroyChildren();
            // todo Die动画
        }

        roleLive() {
            if (this.invincibleAni.length > 0) {
                return;
            }
            let up = Sail.Utils.createSkeleton('res/game/role/Invincible_up');
            up.pos(this.pivotX, this.pivotY);
            this.addChild(up);
            let down = Sail.Utils.createSkeleton('res/game/role/Invincible_down');
            down.pos(this.pivotX, this.pivotY);
            this.addChildAt(down, this.getChildIndex(this.hero));
            up.play(0, true);
            down.play(0, true);
            this.invincibleAni.push(up);
            this.invincibleAni.push(down);
        }

        roleStatusNormal() {
            this.invincibleAni.forEach(function (element) {
                element.destroy();
            }, this);
            this.invincibleAni = [];
        }

        setStatus() {
            if (this.invincibleAni.length > 0 && this.status != ROLE_STATUS.REBORN) {
                this.roleStatusNormal();
            }
            if (this.status == ROLE_STATUS.HIDING) {
                this.alpha = this.isVisual ? 0.5 : 0;
            } else {
                this.alpha = 1;
            }
            switch (this.status) {
                case ROLE_STATUS.HIT:
                    this.hero.play('hit', false);
                    break;
                case ROLE_STATUS.HIT_BACK:
                    this.hero.play('hit', false);
                    break;
                case ROLE_STATUS.REBORN:
                    this.roleLive(); // 重生
                    break;
                case ROLE_STATUS.DIE:
                    this.roleDie();
                    break;
            }
        }

        //updata 同步算法
        active(data) {
            if (this.isDie) {
                this.isDie = false;
                this.pos(data.positionX, data.positionY);
                Sail.io.publish('map.add', this);
                if (GM.user_id == this.uid) {
                    Sail.io.publish('role.move', { x: this.x, y: this.y });
                }
            }
            this.hp = data.hp;
            this.lb_hp.text = this.hp;
            this.bulletNum = data.bulletNum;
            // this.skillPower = data.skillPower;
            this.direct = data.direct;
            this.speedN = data.speedN;
            this.status = data.status;
            this.isVisual = data.isVisual

            for (let i = 0; i < this.heroData.bulletMaxNum; i++) {
                this['b' + i].visible = i < this.bulletNum ? true : false;
            }

            this.hpBar.width = 75 * this.hp / this.heroData.maxHp;

            if (data.clip && GM.user_id != this.uid) {
                this.hero.changeWeaponRotation(Math.atan2(data.clip.x1 - data.clip.x, data.clip.y1 - data.clip.y) * 180 / Math.PI);
            }

            if (this.status == ROLE_STATUS.HIT_BACK) {
                Laya.Tween.to(this, { x: data.positionX, y: data.positionY }, 50, null, null, null, true);
                return;
            }

            //没速度显示静止动画
            if (this.speedN == 0) {
                this.pos(data.positionX, data.positionY);
                this.walkStatus = 0;
                this.setStatus();
                return;
            }
            let lossTime = 0;
            this.startMove(lossTime, data.positionX, data.positionY);
        }

        startMove(lossTime, positionX, positionY) {
            //获得补偿位移
            let eDis = lossTime * this.speed / 1000;
            let eDirectDis = Math.sqrt(Math.pow(this.direct[0], 2) + Math.pow(this.direct[1], 2));
            let ex = positionX + (eDis / eDirectDis) * this.direct[0];
            let ey = positionY + (eDis / eDirectDis) * this.direct[1];
            //获得位移补偿后的真正向量
            let x1 = ex - this.x;
            let y1 = ey - this.y;
            //补偿后的真正距离
            let dis1 = Math.sqrt(x1 * x1 + y1 * y1);
            //英雄脸的朝向
            if (!this.indicatorActive && !this.isAttack && Math.abs(x1) > 0.99) {
                this.setGroupFace(x1 > 0 ? 1 : -1);
            }
            this.frameNum = 0;
            //将距离分N帧渲染
            Laya.timer.frameLoop(1, this, this.move, [x1, y1, dis1 / 3]);
        }

        move(x1, y1, dis1) {
            this.frameNum += 1;
            let x, y, dis;
            //超过50毫秒后按照当前速度向量继续行走
            if (this.frameNum > 3) {
                if (this.frameNum > 6) Laya.timer.clear(this, this.move);
                x = this.direct[0];
                y = this.direct[1];
                dis = this.speed * this.speedN / 1000 * (50 / 3);
            } else {
                x = x1;
                y = y1;
                dis = dis1;
            }
            //记录行走状态 0-停止 1-行走
            this.walkStatus = (dis > 0) ? 1 : 0;
            //距离为0时取消帧动画
            if (dis == 0) {
                Laya.timer.clear(this, this.move);
                return;
            }
            let directDis = Math.sqrt(x * x + y * y);
            let targetX = this.x + (dis / directDis) * x;
            let targetY = this.y + (dis / directDis) * y;
            this.pos(targetX, targetY);
            this.zOrder = targetY;
            if (this.frameNum == 3) {
                this.setStatus();
            }

            //更新地图中心点位置
            if (this.uid == GM.user_id) {
                Sail.io.publish('role.move', { x: targetX, y: targetY });
            }
        }

        //更新脸朝向以及武器角度
        showIndicator(direct) {
            this.indicatorActive = true;
            let angle = Math.atan2(direct[1], direct[0]) * 180 / Math.PI;
            this.setGroupFace(direct[0] > 0 ? 1 : -1);
            if (this.uid == GM.user_id) {
                this.hero.changeWeaponRotation(angle);
            }
        }

        hideIndicator() {
            this.indicatorActive = false;
            if (!this.isAttack) {
                this.hero.resetWeaponRotation();
            }
        }

        //播放攻击动画
        attack(angle) {
            this.isAttack = true;
            this.hero.changeWeaponRotation(angle);
            this.hero.attack();
            if (this.uid == GM.user_id) {
                Sail.io.publish("map.event", { e: "shake", level: 1 });
            }
        }

        localCollision(role) {

        }

        shouldBroadcastMotion() {

        }

        //获取脸的朝向
        getFace() {
            return this.hero.getFace();
        }

        get walkStatus() {
            return this._walkStatus;
        }

        set walkStatus(value) {
            if (this._walkStatus == value) {
                return;
            }
            this._walkStatus = value;
            switch (value) {
                case 1:
                    this.hero.play('walk');
                    let stepAni = this.stepAni;
                    if (!stepAni) {
                        stepAni = this.stepAni = Sail.Utils.createSkeleton("res/game/animation/role_step");
                        stepAni.x = this.getFace() == -1 ? 75 : 10;
                        stepAni.y = 140;
                        this.addChild(stepAni);
                    }
                    stepAni.visible = true;
                    stepAni.play(0, true);
                    break;
                case 0:
                    this.hero.play('standby');
                    if (this.stepAni) {
                        this.stepAni.stop();
                        this.stepAni.visible = false;
                    }
                    break;
            }
        }

        setGroupFace(val) {
            this.hero.setFace(val);
            if (this.stepAni && !this.stepAni.destroyed) {
                this.stepAni.scaleX = val;
                this.stepAni.x = val == -1 ? 75 : 10;
            }
        }

    }

    Sail.class(Role, "Com.Room.Role");
}